package git.soulbgm.utils;

import java.time.ZoneId;
import java.util.Calendar;

/**
 * BD日期工具类
 *
 * @author SoulBGM
 * @date 2024-09-26
 */
public class ExtendDateUtil extends DateUtil {


    private static final Calendar BD_TIME_START_CALENDER;
    private static final Calendar GPS_TIME_START_CALENDER;

    static {
        BD_TIME_START_CALENDER = Calendar.getInstance(TIME_ZONE_UTC);
        BD_TIME_START_CALENDER.setTime(parse("2006-01-01 00:00:00.000"));
        GPS_TIME_START_CALENDER = Calendar.getInstance(TIME_ZONE_UTC);
        GPS_TIME_START_CALENDER.setTime(parse("1980-01-06 00:00:00.000"));
    }

    /**
     * 周内秒
     *
     * @param calendar 日历
     * @return int
     */
    public static long secondsWeek(Calendar startCalender, Calendar calendar) {
        Calendar start = (Calendar) startCalender.clone();
        int week = week(startCalender, calendar);
        offsetDate(start, DAY, week * 7);

        return (calendar.getTimeInMillis() - start.getTimeInMillis()) / 1000;
    }

    public static long bdSecondsWeek(Calendar calendar) {
        return secondsWeek(BD_TIME_START_CALENDER, calendar);
    }

    public static long gpsSecondsWeek(Calendar calendar) {
        return secondsWeek(GPS_TIME_START_CALENDER, calendar);
    }

    /**
     * 计算给定UTC时间对应的北斗周
     *
     * @param calendar 日历
     * @return int
     */
    public static int week(Calendar startCalender, Calendar calendar) {
        long diff = calendar.getTimeInMillis() - startCalender.getTimeInMillis();
        return (int) (diff / MILLISECONDS_PER_WEEK);
    }

    public static int bdWeek(Calendar calendar) {
        return week(BD_TIME_START_CALENDER, calendar);
    }

    public static int gpsWeek(Calendar calendar) {
        return week(GPS_TIME_START_CALENDER, calendar);
    }

    /**
     * 通过北斗周和周内秒获取日历
     *
     * @param bdWeek      北斗周
     * @param secondsWeek 周内秒
     * @return {@link Calendar}
     */
    public static Calendar convertCalendar(Calendar startCalender, int bdWeek, long secondsWeek) {
        Calendar start = (Calendar) startCalender.clone();
        return getCalendar(offsetDate(start, DAY, bdWeek * 7).getTimeInMillis() + (secondsWeek * 1000));
    }

    public static Calendar bdConvertCalendar(int bdWeek, long secondsWeek) {
        return convertCalendar(BD_TIME_START_CALENDER, bdWeek, secondsWeek);
    }

    public static Calendar gpsConvertCalendar(int bdWeek, long secondsWeek) {
        return convertCalendar(GPS_TIME_START_CALENDER, bdWeek, secondsWeek);
    }

    public static void main(String[] args) {
        Calendar calendar = Calendar.getInstance(TIME_ZONE_UTC);
        System.out.println("年积日 : " + getDayOfYear(calendar));
        int bdWeek = bdWeek(calendar);
        System.out.println("北斗周 : " + bdWeek);
        long bdSecondsWeek = bdSecondsWeek(calendar);
        System.out.println("北斗周内秒 : " + bdSecondsWeek);
        System.out.println("北斗周和周内秒组合时间 : " + format(bdConvertCalendar(bdWeek, bdSecondsWeek).getTimeInMillis(), createFormatter(NORM_DATETIME_MS_PATTERN, TIME_ZONE_UTC.toZoneId())));
        System.out.println("-------------------------------------------------");
        int gpsWeek = gpsWeek(calendar);
        System.out.println("GPS周 : " + gpsWeek);
        long gpsSecondsWeek = gpsSecondsWeek(calendar);
        System.out.println("GPS周内秒 : " + gpsSecondsWeek);
        System.out.println("GPS周和周内秒组合时间 : " + format(gpsConvertCalendar(gpsWeek, gpsSecondsWeek).getTimeInMillis(), createFormatter(NORM_DATETIME_MS_PATTERN, TIME_ZONE_UTC.toZoneId())));
    }

}
